package com.dingli.framework.filter;

import com.dingli.framework.entity.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Component
@WebFilter(urlPatterns = "/*")
public class GlobalFilter implements Filter {

    @Value("${security.check}")
    private Boolean check;
    @Value("${security.access}")
    private String access;

    public static ConcurrentHashMap<String, Long> onlines = new ConcurrentHashMap<>();

    public static String add(User user) {
        String token = "Bearer " + Base64Coder.encodeString(user.toString());
        onlines.put(token, System.currentTimeMillis());
        return token;
    }


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html");

        String uri = request.getRequestURI();
        if (check && !uri.endsWith(".js") && !uri.endsWith(".css") &&
                !access.contains(uri)) {
            String token = request.getHeader("Authorization");
            if (token == null || !onlines.containsKey(token)) {
                request.getRequestDispatcher("/system/needLogin").forward(request, response);
                return;
            }
        }

        filterChain.doFilter(request, response);
    }


    @Override
    public void init(FilterConfig filterConfig) {
        if (check) {
            ScheduledExecutorService es = Executors.newScheduledThreadPool(1);
            Runnable task = () -> onlines.entrySet().removeIf(entry ->
                    System.currentTimeMillis() - entry.getValue() > 30 * 60 * 1000);
            es.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
        }
    }


}
